package com.wql.cookie;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;

import com.wql.crypto.AESUtils;

/**
 * Cookie通用操作类
 * 
 * @author wuqinglong
 * @time 2013年11月6日 上午8:47:48
 * @email hellowql@126.com
 * 
 */
public class CookieUtils {

	// 私有化构造函数
	private CookieUtils() {
	}

	/**
	 * 添加Cookie常用方法
	 * 
	 * @param response
	 * @param cookieName
	 * @param cookieValue
	 */
	public static void add(HttpServletResponse response, String cookieName, String cookieValue) {
		if (StringUtils.isNotBlank(cookieName) && StringUtils.isNotBlank(cookieValue)) {
			add(response, new CookieOption().setName(cookieName).setValue(cookieValue));
		}
	}

	/**
	 * 获取Cookie对象
	 * 
	 * @param request
	 * @param cookieName
	 * @return
	 */
	public static Cookie get(HttpServletRequest request, String cookieName) {
		if (StringUtils.isNotBlank(cookieName)) {
			Cookie[] cookies = request.getCookies();
			if (null != cookies) {
				for (Cookie cookie : cookies) {
					if (cookieName.equals(cookie.getName())) {
						return cookie;
					}
				}
			}
		}
		return null;
	}

	/**
	 * 获取Cookie值的常用方法
	 * 
	 * @param request
	 * @param cookieName
	 * @return
	 */
	public static String getValue(HttpServletRequest request, String cookieName) {
		return getValue(request, new CookieOption().setName(cookieName));
	}

	/**
	 * 删除Cookie常用方法
	 * 
	 * @param request
	 * @param response
	 * @param cookieName
	 */
	public static void delete(HttpServletRequest request, HttpServletResponse response, String cookieName) {
		Cookie c = get(request, cookieName);
		if (null != c) {
			c.setMaxAge(0);
			response.addCookie(c);
		}
	}

	/**
	 * 添加Cookie底层方法
	 * 
	 * @param response
	 * @param opt
	 */
	public static void add(HttpServletResponse response, CookieOption opt) {
		if (null != opt && StringUtils.isNotBlank(opt.getName()) && StringUtils.isNotBlank(opt.getValue())) {
			if (opt.getHttpOnly()) {
				response.addHeader("Set-Cookie", setOpt(opt));
			} else {
				try {
					Cookie c = new Cookie(opt.getName(),
							URLEncoder.encode(AESUtils.encrypt(opt.getValue()), "utf-8"));
					setOpt(opt, c);
					response.addCookie(c);
				} catch (UnsupportedEncodingException e) {
					e.printStackTrace();
				}
			}
		}
	}

	/**
	 * 获取Cookie值底层方法
	 * 
	 * @param request
	 * @param opt
	 * @return
	 */
	public static String getValue(HttpServletRequest request, CookieOption opt) {
		if (null != opt && StringUtils.isNotBlank(opt.getName())) {
			Cookie c = get(request, opt.getName());
			if (null != c) {
				try {
					return opt.setValue(AESUtils.decrypt(URLDecoder.decode(c.getValue(), "utf-8"))).getValue();
				} catch (UnsupportedEncodingException e) {
					e.printStackTrace();
				}
			}
		}
		return null;
	}

	/**
	 * Cookie参数拼装
	 * 
	 * @param opt
	 * @param c
	 */
	private static void setOpt(CookieOption opt, Cookie c) {
		if (null == opt || null == c) {
			return;
		}
		if (StringUtils.isNotBlank(opt.getPath())) {
			c.setPath(opt.getPath());
		}
		if (StringUtils.isNotBlank(opt.getDomain())) {
			c.setPath(opt.getDomain());
		}
		if (null != opt.getSecure()) {
			c.setSecure(opt.getSecure());
		}
		if (null != opt.getMaxAge()) {
			c.setMaxAge(opt.getMaxAge());
		}
	}

	/**
	 * Cookie参数拼装
	 * 
	 * @param opt
	 */
	private static String setOpt(CookieOption opt) {
		if (null != opt) {
			StringBuilder sb = new StringBuilder(100);
			try {
				sb.append(opt.getName()).append("=")
						.append(URLEncoder.encode(AESUtils.encrypt(opt.getValue()), "utf-8"));
				if (StringUtils.isNotBlank(opt.getPath())) {
					sb.append(";Path=").append(opt.getPath());
				}
				if (StringUtils.isNotBlank(opt.getDomain())) {
					sb.append(";Domain=").append(opt.getDomain());
				}
				if (null != opt.getMaxAge()) {
					sb.append(";Max-Age=").append(opt.getMaxAge());
				}
				if (null != opt.getSecure() && opt.getSecure()) {
					sb.append(";Secure");
				}
				if (null != opt.getHttpOnly() && opt.getHttpOnly()) {
					sb.append(";HTTPOnly");
				}
				return sb.toString();
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

}
